// local_storage.go
// 本文件实现了基于本地文件系统的简单存储功能，
// 提供了数据的保存（Save）和加载（Load）方法，
// 主要用于将配置信息或其他数据持久化到用户主目录下的指定文件。
//
// 适用于需要轻量级本地持久化的场景。
package storage

import (
	"io"
	"os"
	"path/filepath"
)

// localStorage 结构体用于管理本地存储的文件路径。
type localStorage struct {
	ConfigPath string // 配置文件的完整路径
}

// NewLocalStorage 创建一个 localStorage 实例，
// 并将存储文件路径设置为用户主目录下的 filename。
// 如果无法获取用户主目录，则返回 nil。
func NewLocalStorage(filename string) *localStorage {
	userHomeDir, err := os.UserHomeDir()
	if err != nil {
		return nil
	}
	return &localStorage{
		ConfigPath: filepath.Join(userHomeDir, filename),
	}
}

// ensureFileExists 检查存储文件是否存在，
// 如果不存在则创建一个空文件。
func (ls *localStorage) ensureFileExists() error {
	if _, err := os.Stat(ls.ConfigPath); os.IsNotExist(err) {
		// 确保目录存在
		dir := filepath.Dir(ls.ConfigPath)
		if err := os.MkdirAll(dir, 0755); err != nil {
			return err
		}

		// 创建文件并写入初始内容
		file, err := os.Create(ls.ConfigPath)
		if err != nil {
			return err
		}
		defer file.Close()

		// 写入初始的 YAML 结构
		initialContent := []byte("# NaviDog 配置文件\n# 此文件用于存储数据库连接配置信息\n\n# 数据库连接配置映射\nconnections: {}\n")
		if _, err := file.Write(initialContent); err != nil {
			return err
		}
	}
	return nil
}

// Save 将数据 data 写入到本地存储文件中。
// 如果文件不存在会自动创建。
// 写入时会覆盖原有内容。
func (ls *localStorage) Save(data []byte) error {
	// 文件路径是否存在，不存在则创建
	if err := ls.ensureFileExists(); err != nil {
		return err
	}
	// 文件存在，写入文件
	file, err := os.OpenFile(ls.ConfigPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
	if err != nil {
		return err
	}
	defer file.Close()
	_, err = file.Write(data)
	return err
}

// Load 从本地存储文件中读取全部数据并返回。
// 如果文件不存在则自动创建一个新的配置文件。
func (ls *localStorage) Load() ([]byte, error) {
	// 确保文件存在
	if err := ls.ensureFileExists(); err != nil {
		return nil, err
	}

	// 读取文件内容
	file, err := os.Open(ls.ConfigPath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	data, err := io.ReadAll(file)
	if err != nil {
		return nil, err
	}
	return data, nil
}
